package com.mall.untils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class HttpClientUtil {
	
	/**
	   Invalid use of SingleClientConnManager: connection still allocated 错误，主要有两种：
		1 同一个httpclient当 前一个post|get请求尚未结束，另条线程又再次使用该httpclient请求数据，则前一个会报出如上错误
		2   多线程同步问题：
		
		httpclient默认使用的是SingleClientConnManager，但在并发环境下最好使用ThreadSafeClientConnManager。代码如下：
		HttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager());
	 */
	private static HttpClient hc = new DefaultHttpClient(new ThreadSafeClientConnManager());
	private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	
	
	
	
	
	/**
	 * Get请求
	 * @param url
	 * @param params
	 * @return
	 */
	public static String get(String url, List<NameValuePair> params) {
		String body = null;
		try {
			// Get请求
			HttpGet httpget = new HttpGet(url);
			// 设置参数
            String str = "";
            if(params==null){
                httpget.setURI(new URI(httpget.getURI().toString()));
            } else{
                str = EntityUtils.toString(new UrlEncodedFormEntity(params,"utf-8"));
                httpget.setURI(new URI(httpget.getURI().toString() + "?" + str));
            }
			// 发送请求
			HttpResponse httpresponse = hc.execute(httpget);
			// 获取返回数据
			HttpEntity entity = httpresponse.getEntity();
			body = EntityUtils.toString(entity);
			if (entity != null) {
				EntityUtils.consume(entity); 
//				entity.consumeContent();
			}
		} 
		catch (Exception e) {
			logger.error("getKdgnNews access failed!" , e);
		}
		return body;
	}

	/**
	 * // Post请求
	 * @param url
	 * @param params
	 * @return
	 */
	public static String post(String url, List<NameValuePair> params) {
		String body = null;
//		hc.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"utf-8");
		try {
			// Post请求
			HttpPost httppost = new HttpPost(url);
			// 设置参数
			httppost.setEntity(new UrlEncodedFormEntity(params , HTTP.UTF_8));

			// 发送请求
			HttpResponse httpresponse = hc.execute(httppost);
			// 获取返回数据
			HttpEntity entity = httpresponse.getEntity();
			body = EntityUtils.toString(entity);
			if (entity != null) {
				EntityUtils.consume(entity); 
//				entity.consumeContent();
			}
		} catch (Exception e) {
			logger.error("post access failed!" , e);
		}
		return body;
	}


	/**
	 * 发送HttpPost请求 以json包的形式进行数据传输
	 * 
	 * @param strURL
	 *            服务地址
	 * @param params
	 *            json字符串,例如: "{ \"id\":\"12345\" }" ;其中属性名必须带双引号<br/>
	 * @return 成功:返回json字符串<br/>
	 */
	public static String postJson(String strURL, String params) {
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			System.out.println(url);
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setInstanceFollowRedirects(true);
			connection.setRequestMethod("POST"); // 设置请求方式
			connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
			connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
			connection.connect();
			OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
			out.append(params);
			out.flush();
			out.close();
			// 读取响应
			int length = (int) connection.getContentLength();// 获取长度
			InputStream is = connection.getInputStream();
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8"); // utf-8编码
				System.out.println(result);
				return result;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "error"; // 自定义错误信息
	}

	public static HashMap<String,String> postXml(String urlStr, String xmlInfo){
		HashMap<String, String> map = new HashMap<String, String>();
		try{
			URL url = new URL(urlStr);  
	        URLConnection con = url.openConnection();  
	        con.setDoOutput(true);  
	        con.setRequestProperty("Pragma:", "no-cache");  
	        con.setRequestProperty("Cache-Control", "no-cache");  
	        con.setRequestProperty("Content-Type", "text/xml");  

	        OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),"UTF-8");      
	        System.out.println("urlStr=" + urlStr);  
	        System.out.println("xmlInfo=" + xmlInfo);  
	        out.write(xmlInfo);  //utf-8
	        out.flush();  
	        out.close();  
//	        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));  
//	        String line = "";  
//	        for (line = br.readLine(); line != null; line = br.readLine()) {  
//	            System.out.println(line);  
//	        }  
	        
	        InputStream inputStream = con.getInputStream();
			// 读取输入流
			SAXReader reader = new SAXReader();
			Document document;
			try {
				document = reader.read(inputStream);
			} catch (Exception e) {
				e.printStackTrace();
				return map;
			}
			// 得到xml根元素
			Element root = document.getRootElement();
			// 得到根元素的所有子节点
			List<Element> elementList = root.elements();
			// 遍历所有子节点
			for (Element e : elementList) {
				map.put(e.getName(), e.getText());
			}

			// 释放资源
			inputStream.close();
			inputStream = null;
	        
		}catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	
	
	
	

}
